//
// Created by zzh on 2020/12/10.
//

#ifndef FFMPEGOPENCV_SAFEQUEUE_H
#define FFMPEGOPENCV_SAFEQUEUE_H

#include <queue>
#include <pthread.h>

using namespace std;

template<typename T>
class SafeQueue {
private:
    queue<T> q;
    pthread_mutex_t mutex; //互斥锁
    pthread_cond_t cond; //通知唤醒变量

public:
    SafeQueue() {
        pthread_mutex_init(&mutex, 0);
        pthread_cond_init(&cond, 0);
    }

    ~SafeQueue() {
        pthread_mutex_destroy(&mutex);
        pthread_cond_destroy(&cond);
    }

    //入队
    void push(T value) {
        pthread_mutex_lock(&mutex);
        q.push(value);
        pthread_cond_signal(&cond); //通知有数据到
        pthread_mutex_unlock(&mutex);
    }

    //取出数据 ,失败为0，不为0则成功
    int pop(T &value) {
        int ret = 0;
        pthread_mutex_lock(&mutex);
        //当队列为空时，等待
        while (q.empty()) {
            pthread_cond_wait(&cond, &mutex);
        }
        if (!q.empty()) {
            value = q.front(); //返回数据给引用
            q.pop();
            ret = 1;
        }
        pthread_mutex_unlock(&mutex);
        return ret;
    }

};


#endif //FFMPEGOPENCV_SAFEQUEUE_H
